<template>
  <el-dialog
    v-model="dialogVisible"
    :title="$t('page.system.role.assignPermission')"
    width="600px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div v-loading="loading" class="permission-content">
      <ElTreeComponent
        ref="treeRef"
        :data="menuTree"
        :props="treeProps"
        show-checkbox
        node-key="id"
        :default-checked-keys="checkedKeys"
        :check-strictly="false"
        class="menu-tree"
      />
    </div>
    
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">
          {{ $t('page.system.role.cancel') }}
        </el-button>
        <el-button type="primary" :loading="submitLoading" @click="handleSubmit">
          {{ $t('page.system.role.save') }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import type { ElTree } from 'element-plus';
import {
  ElButton,
  ElDialog,
  ElMessage,
  ElTree as ElTreeComponent,
} from 'element-plus';

import { getRoleMenuTreeApi } from '#/api/system/menu';
import { assignRoleMenuApi, addRoleMenuPermissionsApi, getRoleMenuIdsApi } from '#/api/system/role';
import { $t } from '#/locales';

interface MenuItem {
  id: number;
  title: string;
  children?: MenuItem[];
}

interface Props {
  visible: boolean;
  roleId: number;
  useNewApi?: boolean; // 是否使用新的角色权限关联API
}

interface Emits {
  (e: 'update:visible', value: boolean): void;
  (e: 'submit'): void;
}

const props = withDefaults(defineProps<Props>(), {
  useNewApi: false,
});
const emit = defineEmits<Emits>();

const dialogVisible = computed({
  get: () => props.visible,
  set: (value) => emit('update:visible', value),
});

const treeRef = ref<InstanceType<typeof ElTreeComponent>>();
const loading = ref(false);
const submitLoading = ref(false);
const menuTree = ref<MenuItem[]>([]);
const checkedKeys = ref<number[]>([]);

// 树形组件配置
const treeProps = {
  children: 'children',
  label: 'title',
};

// 获取菜单树和角色权限
const getMenuTreeAndPermissions = async () => {
  if (!props.roleId) return;
  
  try {
    loading.value = true;
    const data = await getRoleMenuTreeApi(props.roleId);
    // 根据实际API响应结构：{ menuTree: [...], checkedKeys: [...] }
    menuTree.value = transformMenuData(data.menuTree || []);
    checkedKeys.value = data.checkedKeys || [];
  } catch (error) {
    console.error('获取菜单列表和权限失败:', error);
  } finally {
    loading.value = false;
  }
};

// 转换菜单数据格式
const transformMenuData = (menus: any[]): MenuItem[] => {
  return menus.map(menu => ({
    id: menu.id,
    title: menu.menuName || menu.name || menu.title || '',
    children: menu.children ? transformMenuData(menu.children) : undefined,
  }));
};

// 监听弹窗显示状态
watch(
  () => props.visible,
  (visible) => {
    if (visible && props.roleId) {
      getMenuTreeAndPermissions();
    }
  }
);

// 提交权限分配
const handleSubmit = async () => {
  if (!props.roleId || !treeRef.value) return;
  
  try {
    submitLoading.value = true;
    
    // 获取选中的节点（包括半选中的父节点）
    const checkedNodes = treeRef.value.getCheckedNodes();
    const halfCheckedNodes = treeRef.value.getHalfCheckedNodes();
    
    const allCheckedIds = [
      ...checkedNodes.map((node: any) => node.id),
      ...halfCheckedNodes.map((node: any) => node.id),
    ];
    
    // 根据配置选择使用哪个API
    if (props.useNewApi) {
      // 使用新的角色权限关联API
      await addRoleMenuPermissionsApi({
        roleId: props.roleId,
        menuIds: allCheckedIds,
      });
    } else {
      // 使用原有的权限分配API
      await assignRoleMenuApi({
        id: props.roleId,
        menuIds: allCheckedIds,
      });
    }
    
    emit('submit');
    handleClose();
  } catch (error) {
    console.error('分配权限失败:', error);
  } finally {
    submitLoading.value = false;
  }
};

// 关闭弹窗
const handleClose = () => {
  dialogVisible.value = false;
  menuTree.value = [];
  checkedKeys.value = [];
};
</script>

<style scoped>
.permission-content {
  max-height: 400px;
  overflow-y: auto;
}

.menu-tree {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
}

.dialog-footer {
  text-align: right;
}
</style> 
 